<template>
  <AdminLayout @show-category-modal="showCategoryModal = true">
    <div class="music-management">
          <!-- 页面标题和操作 -->
          <div class="page-header">
            <div class="header-left">
              <h1>音乐管理</h1>
              <p class="page-subtitle">管理平台上的所有音乐内容</p>
            </div>
            <div class="header-actions">
              <button @click="showUploadModal = true" class="upload-btn">
                <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
                  <path d="M19,13H13V19H11V13H5V11H11V5H13V11H19V13Z"/>
                </svg>
                上传音乐
              </button>
            </div>
          </div>

          <!-- 搜索和过滤 -->
          <div class="filters">
            <div class="search-box">
              <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
                <path d="M9.5,3A6.5,6.5 0 0,1 16,9.5C16,11.11 15.41,12.59 14.44,13.73L14.71,14H15.5L20.5,19L19,20.5L14,15.5V14.71L13.73,14.44C12.59,15.41 11.11,16 9.5,16A6.5,6.5 0 0,1 3,9.5A6.5,6.5 0 0,1 9.5,3M9.5,5C7,5 5,7 5,9.5C5,12 7,14 9.5,14C12,14 14,12 14,9.5C14,7 12,5 9.5,5Z"/>
              </svg>
              <input 
                v-model="searchKeyword" 
                placeholder="搜索音乐标题、艺术家..."
                @input="searchMusic"
              />
            </div>
            <select v-model="selectedCategory" @change="filterByCategory" class="category-filter">
              <option value="">所有分类</option>
              <option v-for="category in categories" :key="category.categoryId" :value="category.categoryId">
                {{ category.name }}
              </option>
            </select>
            <!-- 批量删除按钮 -->
            <button 
              v-if="selectedMusicIds.length > 0" 
              @click="batchDeleteMusic" 
              :disabled="batchDeleting" 
              class="batch-delete-btn-filter"
            >
              <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
                <path d="M19,4H15.5L14.5,3H9.5L8.5,4H5V6H19M6,19A2,2 0 0,0 8,21H16A2,2 0 0,0 18,19V7H6V19Z"/>
              </svg>
              {{ batchDeleting ? '删除中...' : `批量删除 (${selectedMusicIds.length})` }}
            </button>
          </div>

          <!-- 音乐列表 -->
          <div class="music-table-container">
            <table class="music-table">
              <thead>
                <tr>
                  <th class="checkbox-col">
                    <input 
                      type="checkbox" 
                      v-model="selectAll" 
                      @change="toggleSelectAll"
                      class="checkbox"
                    >
                  </th>
                  <th>封面</th>
                  <th>标题</th>
                  <th>艺术家</th>
                  <th>时长</th>
                  <th>分类</th>
                  <th>上传时间</th>
                  <th>播放次数</th>
                  <th>操作</th>
                </tr>
              </thead>
              <tbody>
                <tr v-for="music in musicList" :key="music.musicId" class="music-row">
                  <td class="checkbox-col">
                    <input 
                      type="checkbox" 
                      v-model="selectedMusicIds" 
                      :value="music.musicId"
                      @change="updateSelectAll"
                      class="checkbox"
                    >
                  </td>
                  <td>
                    <div class="music-cover">
                      <img v-if="music.coverPath" :src="music.coverPath" :alt="music.name" />
                      <div v-else class="default-cover">
                        <svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
                          <path d="M12 3V13.55C11.41 13.21 10.73 13 10 13C7.79 13 6 14.79 6 17S7.79 21 10 21 14 19.21 14 17V7H18V3H12Z"/>
                        </svg>
                      </div>
                    </div>
                  </td>
                  <td class="music-title">
                    <strong>{{ music.name }}</strong>
                  </td>
                  <td>{{ music.singer }}</td>
                  <td>{{ formatDuration(music.duration) }}</td>
                  <td>
                    <span v-for="category in music.categories" :key="category.categoryId" class="category-tag">
                      {{ category.name }}
                    </span>
                    <span v-if="!music.categories || music.categories.length === 0">-</span>
                  </td>
                  <td>{{ formatDate(music.uploadTime) }}</td>
                  <td>{{ formatNumber(music.playCount) }}</td>
                  <td>
                    <div class="action-buttons">
                      <button @click="editMusic(music)" class="edit-btn" title="编辑">
                        <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
                          <path d="M20.71,7.04C21.1,6.65 21.1,6 20.71,5.63L18.37,3.29C18,2.9 17.35,2.9 16.96,3.29L15.12,5.12L18.87,8.87M3,17.25V21H6.75L17.81,9.93L14.06,6.18L3,17.25Z"/>
                        </svg>
                      </button>
                      <button @click="deleteMusic(music)" class="delete-btn" title="删除">
                        <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
                          <path d="M19,4H15.5L14.5,3H9.5L8.5,4H5V6H19M6,19A2,2 0 0,0 8,21H16A2,2 0 0,0 18,19V7H6V19Z"/>
                        </svg>
                      </button>
                    </div>
                  </td>
                </tr>
              </tbody>
            </table>
          </div>

          <!-- 分页 -->
          <div class="pagination">
            <button 
              @click="changePage(currentPage - 1)" 
              :disabled="currentPage === 0"
              class="page-btn"
            >
              上一页
            </button>
            <span class="page-info">
              第 {{ currentPage + 1 }} 页，共 {{ totalPages }} 页
            </span>
            <button 
              @click="changePage(currentPage + 1)" 
              :disabled="currentPage >= totalPages - 1"
              class="page-btn"
            >
              下一页
            </button>
          </div>
        </div>

    <!-- 上传/编辑音乐模态框 -->
    <div v-if="showUploadModal" class="modal-overlay" @click="closeUploadModal">
      <div class="modal-content" @click.stop>
        <div class="modal-header">
          <h3>{{ editingMusic ? '编辑音乐' : '上传音乐' }}</h3>
          <button @click="closeUploadModal" class="close-btn">
            <svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
              <path d="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z"/>
            </svg>
          </button>
        </div>
        
        <div class="modal-body">
          <form @submit.prevent="saveMusicData">
            <!-- 基本信息 -->
            <div class="form-section">
              <h4 class="section-title">基本信息</h4>
              <div class="form-row">
                <div class="form-group">
                  <label>音乐标题 *</label>
                  <input v-model="musicForm.title" type="text" required placeholder="请输入音乐标题" />
                </div>
                
                <div class="form-group">
                  <label>艺术家 *</label>
                  <input v-model="musicForm.artist" type="text" required placeholder="请输入艺术家名称" />
                </div>
              </div>
              
              <div class="form-row">
                <div class="form-group">
                  <label>分类 *</label>
                  <select v-model="musicForm.categoryId" required>
                    <option value="">请选择分类</option>
                    <option v-for="category in categories" :key="category.categoryId" :value="category.categoryId">
                      {{ category.name }}
                    </option>
                  </select>
                </div>
                
                <div class="form-group">
                  <label>时长（秒）</label>
                  <div class="duration-input">
                    <input 
                      v-model.number="musicForm.duration" 
                      type="number" 
                      min="0" 
                      placeholder="音乐时长（手动填写或自动获取）"
                      :class="{ 'auto-detected': musicForm.musicFile && musicForm.duration > 0 && !manualDuration }"
                    />
                    <span v-if="musicForm.duration > 0" class="duration-display">
                      {{ formatDuration(musicForm.duration) }}
                    </span>
                    <span v-if="musicForm.musicFile && musicForm.duration > 0 && !manualDuration" class="auto-label">
                      自动获取
                    </span>
                    <span v-if="manualDuration && musicForm.duration > 0" class="manual-label">
                      手动设置
                    </span>
                  </div>
                </div>
                
                <div class="form-group">
                  <label>播放次数</label>
                  <div class="play-count-input">
                    <input 
                      v-model.number="musicForm.playCount" 
                      type="number" 
                      min="0" 
                      placeholder="播放次数"
                    />
                    <span v-if="musicForm.playCount > 0" class="count-display">
                      {{ formatNumber(musicForm.playCount) }}
                    </span>
                  </div>
                </div>
              </div>
            </div>
            
            <!-- 文件上传区域 -->
            <div class="form-section">
              <h4 class="section-title">文件上传 <a href="#" @click.prevent="showTutorial = true" class="tutorial-link">📖 教程</a></h4>
              <div class="upload-container">
                <!-- 音乐文件上传 -->
                <div class="upload-column">
                  <label class="upload-label">音乐文件 *</label>
                  <div class="upload-section">
                    <div class="upload-tabs">
                      <button 
                        type="button" 
                        @click="musicForm.musicUploadType = 'url'" 
                        :class="{ active: musicForm.musicUploadType === 'url' }"
                        class="upload-tab priority"
                      >
                        🎵 URL链接
                      </button>
                      <button 
                        type="button" 
                        @click="musicForm.musicUploadType = 'file'" 
                        :class="{ active: musicForm.musicUploadType === 'file' }"
                        class="upload-tab not-recommended"
                      >
                        📁 文件上传
                      </button>
                    </div>
                    
                    <!-- 文件上传 -->
                    <div v-if="musicForm.musicUploadType === 'file'" class="upload-area">
                      <input 
                        ref="musicFileInput"
                        type="file" 
                        accept="audio/*,.mp3,.wav,.flac,.aac,.ogg,.m4a"
                        @change="handleMusicFileChange"
                        class="file-input"
                        id="musicFile"
                      />
                      <label for="musicFile" class="file-label">
                        <div v-if="!musicForm.musicFile" class="upload-placeholder">
                          <svg width="48" height="48" viewBox="0 0 24 24" fill="currentColor">
                            <path d="M12 3V13.55C11.41 13.21 10.73 13 10 13C7.79 13 6 14.79 6 17S7.79 21 10 21 14 19.21 14 17V7H18V3H12Z"/>
                          </svg>
                          <p>点击选择音乐文件</p>
                          <p class="upload-hint">测试功能有极大可能引起错误</p>
                          <p class="upload-hint">支持 MP3、WAV、FLAC、AAC 等格式，最大50MB</p>
                        </div>
                        <div v-else class="upload-success">
                          <svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
                            <path d="M9,20.42L2.79,14.21L5.62,11.38L9,14.77L18.88,4.88L21.71,7.71L9,20.42Z"/>
                          </svg>
                          <span>{{ musicForm.musicFile.name }}</span>
                          <button type="button" @click="clearMusicFile" class="clear-btn">
                            <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
                              <path d="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z"/>
                            </svg>
                          </button>
                        </div>
                      </label>
                    </div>
                    
                    <!-- 平台选择和ID输入 -->
                    <div v-if="musicForm.musicUploadType === 'url'" class="url-input">
                      <div class="platform-selector">
                        <label class="platform-select-label">选择音乐平台：</label>
                        <div class="platform-buttons">
                          <button 
                            type="button"
                            v-for="platform in testAudioUrls" 
                            :key="platform.platform"
                            @click="selectedPlatform = platform.platform"
                            :class="{ active: selectedPlatform === platform.platform }"
                            class="platform-btn"
                          >
                            {{ platform.name }}
                          </button>
                        </div>
                      </div>
                      
                      <div class="id-input-section">
                        <div class="id-input-group">
                          <input 
                            v-model="musicId" 
                            :type="selectedPlatform === 'custom' ? 'url' : 'text'"
                            :placeholder="getCurrentPlatform().placeholder"
                            :required="musicForm.musicUploadType === 'url'"
                            @input="generateUrlFromId"
                          />
                          <button 
                            type="button" 
                            @click="testGeneratedUrl"
                            class="btn btn-test"
                            :disabled="!musicId || testingUrl"
                            title="测试音频是否可播放"
                          >
                            {{ testingUrl ? '🔄' : '🧪' }} 测试
                          </button>
                        </div>
                        
                        <div class="platform-example">
                          <span class="example-text">
                            示例：{{ getCurrentPlatform().example }}
                          </span>
                        </div>
                        
                        <div v-if="musicForm.musicUrl && selectedPlatform !== 'custom'" class="generated-url">
                          <label>生成的URL：</label>
                          <div class="url-display">{{ musicForm.musicUrl }}</div>
                        </div>
                        
                        <div v-if="urlValidation.message" 
                             class="url-validation" 
                             :class="urlValidation.type">
                          {{ urlValidation.message }}
                        </div>
                      </div>

                      
                      <!-- 音频预览 -->
                      <div v-if="previewAudioUrl" class="audio-preview">
                        <h5>🎵 音频预览：</h5>
                        <audio :src="previewAudioUrl" controls preload="metadata"></audio>
                        <button 
                          type="button" 
                          @click="clearPreview" 
                          class="btn btn-sm btn-outline"
                          title="清除预览"
                        >
                          ✖️ 清除预览
                        </button>
                      </div>
                    </div>
                  </div>
                </div>
                
                <!-- 封面图片上传 -->
                <div class="upload-column">
                  <label class="upload-label">封面图片</label>
                  <div class="upload-section">
                    <div class="upload-tabs">
                      <button 
                        type="button" 
                        @click="musicForm.coverUploadType = 'url'" 
                        :class="{ active: musicForm.coverUploadType === 'url' }"
                        class="upload-tab priority"
                      >
                        🖼️ URL链接
                      </button>
                      <button 
                        type="button" 
                        @click="musicForm.coverUploadType = 'file'" 
                        :class="{ active: musicForm.coverUploadType === 'file' }"
                        class="upload-tab not-recommended"
                      >
                        📁 文件上传
                      </button>
                    </div>
                    
                    <!-- 文件上传 -->
                    <div v-if="musicForm.coverUploadType === 'file'" class="upload-area cover-upload">
                      <input 
                        ref="coverFileInput"
                        type="file" 
                        accept="image/*,.jpg,.jpeg,.png,.gif,.webp"
                        @change="handleCoverFileChange"
                        class="file-input"
                        id="coverFile"
                      />
                      <label for="coverFile" class="file-label">
                        <div v-if="!musicForm.coverFile && !musicForm.coverPreview" class="upload-placeholder cover-placeholder">
                          <svg width="48" height="48" viewBox="0 0 24 24" fill="currentColor">
                            <path d="M8.5,13.5L11,16.5L14.5,12L19,18H5M21,19V5C21,3.89 20.1,3 19,3H5A2,2 0 0,0 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19Z"/>
                          </svg>
                          <p>点击选择封面图片</p>
                          <p class="upload-hint">测试功能有极大可能引起错误</p>
                          <p class="upload-hint">支持 JPG、PNG、GIF 等格式，最大5MB</p>
                        </div>
                        <div v-else class="cover-preview">
                          <img v-if="musicForm.coverPreview" :src="musicForm.coverPreview" alt="封面预览" />
                          <div class="cover-info">
                            <span v-if="musicForm.coverFile">{{ musicForm.coverFile.name }}</span>
                            <button type="button" @click="clearCoverFile" class="clear-btn">
                              <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
                                <path d="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z"/>
                              </svg>
                            </button>
                          </div>
                        </div>
                      </label>
                    </div>
                    
                    <!-- URL输入 -->
                    <div v-if="musicForm.coverUploadType === 'url'" class="url-input">
                      <div class="url-input-group">
                        <input 
                          v-model="musicForm.coverUrl" 
                          type="url" 
                          placeholder="请输入封面图片URL" 
                          @input="updateCoverPreview"
                        />
                        <button 
                          type="button" 
                          @click="testCoverUrl"
                          class="btn btn-test"
                          :disabled="!musicForm.coverUrl"
                          title="测试图片是否可访问"
                        >
                          🧪 测试
                        </button>
                      </div>
                      
                      <!-- 封面预览 -->
                      <div v-if="musicForm.coverUrl" class="cover-url-preview">
                        <h5>🖼️ 封面预览：</h5>
                        <div class="preview-container">
                          <img 
                            :src="musicForm.coverUrl" 
                            alt="封面预览" 
                            @load="onCoverLoad"
                            @error="onCoverError"
                            class="preview-image"
                          />
                          <div v-if="coverUrlStatus" class="preview-status" :class="coverUrlStatus.type">
                            {{ coverUrlStatus.message }}
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
            


            
            <div class="modal-footer">
              <button type="button" @click="closeUploadModal" class="cancel-btn">取消</button>
              <button type="submit" class="submit-btn" :disabled="saving">
                {{ saving ? '保存中...' : (editingMusic ? '更新' : '上传') }}
              </button>
            </div>
          </form>
        </div>
      </div>
    </div>

    <!-- 分类管理模态框 -->
    <div v-if="showCategoryModal" class="modal-overlay" @click="closeCategoryModal">
      <div class="modal-content category-modal" @click.stop>
        <div class="modal-header">
          <h3>分类管理</h3>
          <button @click="closeCategoryModal" class="close-btn">
            <svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
              <path d="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z"/>
            </svg>
          </button>
        </div>
        
        <div class="modal-body">
          <div class="category-management-layout">
            <!-- 新增分类表单 -->
            <div class="category-form-section">
              <div class="section-header">
                <h4>新增分类</h4>
                <span class="section-description">添加新的音乐分类</span>
              </div>
              <form @submit.prevent="saveCategory" class="category-form">
                <div class="form-group">
                  <label>分类名称 *</label>
                  <input v-model="categoryForm.name" type="text" placeholder="请输入分类名称" required />
                </div>
                <div class="form-group">
                  <label>分类描述</label>
                  <input v-model="categoryForm.description" type="text" placeholder="请输入分类描述（可选）" />
                </div>
                <button type="submit" class="add-btn" :disabled="savingCategory">
                  <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
                    <path d="M19,13H13V19H11V13H5V11H11V5H13V11H19V13Z"/>
                  </svg>
                  {{ savingCategory ? '添加中...' : '添加分类' }}
                </button>
              </form>
            </div>
            
            <!-- 分类列表 -->
            <div class="category-list-section">
              <div class="section-header">
                <h4>现有分类</h4>
                <span class="section-description">管理已存在的分类（共{{ categories.length }}个）</span>
              </div>
              <div class="category-list">
                <div v-if="categories.length === 0" class="empty-state">
                  <svg width="48" height="48" viewBox="0 0 24 24" fill="currentColor">
                    <path d="M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4M11,16.5L6.5,12L7.91,10.59L11,13.67L16.59,8.09L18,9.5L11,16.5Z"/>
                  </svg>
                  <p>暂无分类</p>
                  <span>请添加第一个音乐分类</span>
                </div>
                <div v-else class="category-items">
                  <div v-for="category in categories" :key="category.categoryId" class="category-item">
                    <div class="category-info">
                      <div class="category-main">
                        <strong>{{ category.name }}</strong>
                        <span v-if="category.description" class="category-desc">{{ category.description }}</span>
                      </div>
                    </div>
                    <div class="category-actions">
                      <button @click="editCategory(category)" class="edit-btn">
                        <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor">
                          <path d="M20.71,7.04C21.1,6.65 21.1,6 20.71,5.63L18.37,3.29C18,2.9 17.35,2.9 16.96,3.29L15.12,5.12L18.87,8.87M3,17.25V21H6.75L17.81,9.93L14.06,6.18L3,17.25Z"/>
                        </svg>
                        编辑
                      </button>
                      <button @click="deleteCategory(category)" class="delete-btn">
                        <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor">
                          <path d="M19,4H15.5L14.5,3H9.5L8.5,4H5V6H19M6,19A2,2 0 0,0 8,21H16A2,2 0 0,0 18,19V7H6V19Z"/>
                        </svg>
                        删除
                      </button>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    
    <!-- 教程弹窗 -->
    <MusicUrlTutorial v-if="showTutorial" @close="showTutorial = false" />
  </AdminLayout>
</template>

<script>
import AdminLayout from '@/components/AdminLayout.vue'
import MusicUrlTutorial from './MusicUrlTutorial.vue'
import { musicManagement, categoryManagement, fileUpload } from '@/utils/adminApi'

export default {
  name: 'AdminMusicView',
  components: {
    AdminLayout,
    MusicUrlTutorial
  },
  data() {
    return {
      musicList: [],
      categories: [],
      searchKeyword: '',
      selectedCategory: '',
      currentPage: 0,
      totalPages: 0,
      pageSize: 10,
      
      // 模态框状态
      showUploadModal: false,
      showCategoryModal: false,
      showTutorial: false,
      editingMusic: null,
      saving: false,
      savingCategory: false,
      
      // 表单数据
      musicForm: {
        title: '',
        artist: '',
        categoryId: '',
        duration: null,
        playCount: 0,
        musicUrl: '',
        coverUrl: '',
        // 文件上传相关
        musicUploadType: 'url', // 'file' 或 'url' - 默认使用URL
        coverUploadType: 'url', // 'file' 或 'url' - 默认使用URL
        musicFile: null,
        coverFile: null,
        coverPreview: null
      },
      
      categoryForm: {
        name: '',
        description: ''
      },
      
      // 批量操作
      selectedMusicIds: [],
      selectAll: false,
      batchDeleting: false,
      
      // URL验证和测试
      urlValidation: {
        message: '',
        type: 'info' // 'success', 'error', 'warning', 'info'
      },
      testingUrl: false,
      previewAudioUrl: '',
      
      // 平台选择和ID输入
      selectedPlatform: 'netease', // 默认选择网易云音乐
      musicId: '', // 音乐ID输入
      
      // 封面URL状态
      coverUrlStatus: null,
      
      // 时长设置标志
      manualDuration: false, // 标记是否为手动设置的时长
      isFromAudioFile: false, // 标记时长是否来自音频文件自动获取
      
      // 音频平台和示例
      testAudioUrls: [
        {
          name: '网易云音乐',
          platform: 'netease',
          description: '输入歌曲ID即可，例如：1347230688',
          placeholder: '请输入网易云音乐歌曲ID',
          example: '1347230688',
          urlTemplate: 'https://music.163.com/song/media/outer/url?id={ID}.mp3'
        },
        {
          name: 'QQ音乐',
          platform: 'qq',
          description: '输入歌曲mid即可，例如：002J4UUk29y8BY',
          placeholder: '请输入QQ音乐歌曲mid',
          example: '002J4UUk29y8BY',
          urlTemplate: 'https://ws.stream.qqmusic.qq.com/{MID}.m4a'
        },
        {
          name: '酷狗音乐',
          platform: 'kugou',
          description: '输入歌曲hash即可，例如：2C1D1E4B9E9B0F3A2A1A',
          placeholder: '请输入酷狗音乐歌曲hash',
          example: '2C1D1E4B9E9B0F3A2A1A',
          urlTemplate: 'https://webfs.yun.kugou.com/202310/{HASH}.mp3'
        },
        {
          name: '自定义URL',
          platform: 'custom',
          description: '直接输入完整的音频URL链接',
          placeholder: '请输入完整的音频URL链接',
          example: 'https://example.com/music.mp3',
          urlTemplate: '{URL}'
        }
      ]
    }
  },
  
  async mounted() {
    await this.loadCategories()
    await this.loadMusic()
  },
  
  methods: {
    async loadMusic() {
      try {
        const response = await musicManagement.getMusic(this.currentPage, this.pageSize)
        if (response.success) {
          // 处理音乐数据，确保分类信息正确显示
          this.musicList = response.music.map(music => ({
            ...music,
            // 如果有category属性，转换为categories数组格式
            categories: music.category ? [music.category] : []
          }))
          this.totalPages = response.totalPages
        }
      } catch (error) {
        console.error('获取音乐列表失败:', error)
      }
    },
    
    async loadCategories() {
      try {
        const response = await categoryManagement.getCategories()
        if (response.success) {
          this.categories = response.categories
        }
      } catch (error) {
        console.error('获取分类列表失败:', error)
      }
    },
    
    async saveMusicData() {
      this.saving = true
      try {
        // 验证必填字段
        if (!this.musicForm.title?.trim()) {
          this.$root.showToast('请输入音乐标题', 'warning')
          this.saving = false
          return
        }
        if (!this.musicForm.artist?.trim()) {
          this.$root.showToast('请输入艺术家', 'warning')
          this.saving = false
          return
        }
        if (!this.musicForm.categoryId) {
          this.$root.showToast('请选择音乐分类', 'warning')
          this.saving = false
          return
        }
        
        // 准备提交的数据
        let musicData = {
          title: this.musicForm.title.trim(),
          artist: this.musicForm.artist.trim(),
          categoryId: parseInt(this.musicForm.categoryId),
          duration: this.musicForm.duration || 0,  // 如果没有设置时长，默认为0
          playCount: this.musicForm.playCount || 0  // 播放次数
        }
        
        // 添加上传类型到请求数据
        musicData.uploadType = this.musicForm.musicUploadType.toUpperCase() // 'URL' 或 'FILE'
        
        // 处理音乐文件
        if (this.musicForm.musicUploadType === 'url') {
          // URL上传方式（优先）
          if (!this.musicForm.musicUrl?.trim()) {
            throw new Error('请输入音乐URL')
          }
          musicData.externalUrl = this.musicForm.musicUrl.trim()
          musicData.musicUrl = this.musicForm.musicUrl.trim() // 保持兼容性
        } else if (this.musicForm.musicUploadType === 'file' && this.musicForm.musicFile) {
          // 文件上传方式
          const songResponse = await this.uploadSongFile(this.musicForm.musicFile)
          if (songResponse.success) {
            musicData.musicUrl = `http://localhost:2025${songResponse.fileUrl}`
          } else {
            throw new Error('音乐文件上传失败')
          }
        } else {
          throw new Error('请输入音乐URL或选择音乐文件')
        }
        
        // 处理封面图片
        if (this.musicForm.coverUploadType === 'file' && this.musicForm.coverFile) {
          // 上传封面文件
          const coverResponse = await this.uploadCoverFile(this.musicForm.coverFile)
          if (coverResponse.success) {
            musicData.coverUrl = `http://localhost:2025${coverResponse.fileUrl}`
          }
        } else if (this.musicForm.coverUploadType === 'url' && this.musicForm.coverUrl) {
          musicData.coverUrl = this.musicForm.coverUrl
        }
        
        // 提交音乐数据
        let response
        if (this.editingMusic) {
          response = await musicManagement.updateMusic(this.editingMusic.musicId, musicData)
        } else {
          response = await musicManagement.uploadMusic(musicData)
        }
        
        if (response.success) {
          this.$root.showToast(this.editingMusic ? '音乐更新成功！' : '音乐上传成功！', 'success')
          await this.loadMusic()
          this.closeUploadModal()
        }
      } catch (error) {
        console.error('保存音乐失败:', error)
        this.$root.showToast(error.message || '保存音乐失败', 'error')
      } finally {
        this.saving = false
      }
    },
    
    async saveCategory() {
      this.savingCategory = true
      try {
        const response = await categoryManagement.createCategory(this.categoryForm)
        if (response.success) {
          await this.loadCategories()
          this.categoryForm = { name: '', description: '' }
        }
      } catch (error) {
        console.error('保存分类失败:', error)
      } finally {
        this.savingCategory = false
      }
    },
    
    async deleteMusic(music) {
      if (confirm(`确定要删除音乐《${music.name}》吗？此操作不可撤销，相关文件也将被删除。`)) {
        try {
          const response = await musicManagement.deleteMusic(music.musicId)
          if (response.success) {
            this.$root.showToast('音乐删除成功！', 'success')
            await this.loadMusic()
            // 清空选择状态
            this.selectedMusicIds = []
            this.selectAll = false
          } else {
            this.$root.showToast('删除音乐失败', 'error')
          }
        } catch (error) {
          console.error('删除音乐失败:', error)
          this.$root.showToast('删除音乐失败', 'error')
        }
      }
    },
    
    async deleteCategory(category) {
      if (confirm(`确定要删除分类《${category.name}》吗？`)) {
        try {
          const response = await categoryManagement.deleteCategory(category.categoryId)
          if (response.success) {
            await this.loadCategories()
          }
        } catch (error) {
          console.error('删除分类失败:', error)
        }
      }
    },
    
    editMusic(music) {
      this.editingMusic = music
      this.musicForm = {
        title: music.name,
        artist: music.singer,
        categoryId: music.categories?.[0]?.categoryId || '',
        duration: music.duration,
        playCount: music.playCount || 0,
        musicUrl: music.filePath,
        coverUrl: music.coverPath || '',
        description: '',
        musicUploadType: 'url',
        coverUploadType: 'url',
        musicFile: null,
        coverFile: null,
        coverPreview: music.coverPath || null // 设置封面预览
      }
      
      // 自动检测音乐平台
      this.detectMusicPlatform(music.filePath)
      
      // 如果编辑的音乐有时长，标记为手动设置（允许用户修改）
      if (music.duration && music.duration > 0) {
        this.manualDuration = true
        this.isFromAudioFile = false
      }
      
      this.showUploadModal = true
    },
    
    editCategory(category) {
      // 实现分类编辑功能
      console.log('编辑分类:', category)
    },
    
    closeUploadModal() {
      this.showUploadModal = false
      this.editingMusic = null
      this.resetMusicForm()
    },
    
    resetMusicForm() {
      this.musicForm = {
        title: '',
        artist: '',
        categoryId: '',
        duration: null,
        playCount: 0,
        musicUrl: '',
        coverUrl: '',
        description: '',
        musicUploadType: 'url', // 默认使用URL上传
        coverUploadType: 'url', // 默认使用URL上传
        musicFile: null,
        coverFile: null,
        coverPreview: null
      }
      
      // 重置平台选择和ID输入
      this.selectedPlatform = 'netease'
      this.musicId = ''
      this.urlValidation = { message: '', type: 'info' }
      this.previewAudioUrl = ''
      this.coverUrlStatus = null
      
      // 重置时长标志
      this.manualDuration = false
      this.isFromAudioFile = false
      
      // 清空文件输入框
      if (this.$refs.musicFileInput) {
        this.$refs.musicFileInput.value = ''
      }
      if (this.$refs.coverFileInput) {
        this.$refs.coverFileInput.value = ''
      }
    },
    
    // 文件上传相关方法
    handleMusicFileChange(event) {
      const file = event.target.files[0]
      if (file) {
        // 验证文件类型
        const allowedTypes = ['audio/mpeg', 'audio/wav', 'audio/flac', 'audio/aac', 'audio/ogg', 'audio/mp4']
        const allowedExtensions = ['.mp3', '.wav', '.flac', '.aac', '.ogg', '.m4a']
        
        const isValidType = allowedTypes.includes(file.type) || 
                           allowedExtensions.some(ext => file.name.toLowerCase().endsWith(ext))
        
        if (!isValidType) {
          this.$root.showToast('请选择有效的音频文件格式', 'error')
          event.target.value = ''
          return
        }
        
        // 验证文件大小（50MB）
        if (file.size > 50 * 1024 * 1024) {
          this.$root.showToast('音乐文件大小不能超过50MB', 'error')
          event.target.value = ''
          return
        }
        
        this.musicForm.musicFile = file
        
        // 自动获取音频文件时长
        this.getAudioDuration(file)
      }
    },
    
    handleCoverFileChange(event) {
      const file = event.target.files[0]
      if (file) {
        // 验证文件类型
        const allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp']
        const allowedExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.webp']
        
        const isValidType = allowedTypes.includes(file.type) || 
                           allowedExtensions.some(ext => file.name.toLowerCase().endsWith(ext))
        
        if (!isValidType) {
          this.$root.showToast('请选择有效的图片文件格式', 'error')
          event.target.value = ''
          return
        }
        
        // 验证文件大小（5MB）
        if (file.size > 5 * 1024 * 1024) {
          this.$root.showToast('图片文件大小不能超过5MB', 'error')
          event.target.value = ''
          return
        }
        
        this.musicForm.coverFile = file
        
        // 生成预览图
        const reader = new FileReader()
        reader.onload = (e) => {
          this.musicForm.coverPreview = e.target.result
        }
        reader.readAsDataURL(file)
      }
    },
    
    clearMusicFile() {
      this.musicForm.musicFile = null
      this.musicForm.duration = null
      if (this.$refs.musicFileInput) {
        this.$refs.musicFileInput.value = ''
      }
    },
    
    clearCoverFile() {
      this.musicForm.coverFile = null
      this.musicForm.coverPreview = null
      if (this.$refs.coverFileInput) {
        this.$refs.coverFileInput.value = ''
      }
    },
    
    // 获取音频文件时长
    getAudioDuration(file) {
      const audio = new Audio()
      const url = URL.createObjectURL(file)
      
      audio.addEventListener('loadedmetadata', () => {
        // 检查audio.duration是否有效
        if (audio.duration && !isNaN(audio.duration) && isFinite(audio.duration)) {
          // 获取时长（秒）并四舍五入
          const duration = Math.round(audio.duration)
          
          // 如果用户已经手动填写了时长，询问是否要覆盖
          if (this.musicForm.duration && this.musicForm.duration > 0) {
            const shouldOverride = confirm(
              `检测到音频时长为 ${this.formatDuration(duration)}，但您已手动设置为 ${this.formatDuration(this.musicForm.duration)}。\n是否要用检测到的时长覆盖手动设置？`
            )
            if (!shouldOverride) {
              console.log('用户选择保留手动设置的时长:', this.musicForm.duration)
              this.$root.showToast('保留手动设置的时长', 'info')
              URL.revokeObjectURL(url)
              return
            }
          }
          
          // 标记时长来自音频文件自动获取
          this.isFromAudioFile = true
          this.manualDuration = false
          this.musicForm.duration = duration
          
          // 短暂延时后重置标志，允许后续手动修改
          setTimeout(() => {
            this.isFromAudioFile = false
          }, 100)
          
          console.log('设置音频时长:', duration, '秒')
          this.$root.showToast(`音频时长：${this.formatDuration(duration)}`, 'success')
        } else {
          console.warn('音频时长无效:', audio.duration)
          // 只有在用户没有手动设置时长的情况下才重置为0
          if (!this.musicForm.duration || this.musicForm.duration <= 0) {
            this.musicForm.duration = 0
          }
          this.$root.showToast('无法获取音频时长', 'warning')
        }
        
        // 清理URL对象
        URL.revokeObjectURL(url)
      })
      
      audio.addEventListener('error', (e) => {
        // 如果无法获取时长，设置为默认值
        this.musicForm.duration = 0
        URL.revokeObjectURL(url)
        console.error('音频加载失败:', e)
        this.$root.showToast('音频文件加载失败', 'error')
      })
      
      audio.addEventListener('timeout', () => {
        this.musicForm.duration = 0
        URL.revokeObjectURL(url)
        console.warn('音频加载超时')
        this.$root.showToast('音频加载超时', 'warning')
      })
      
      audio.src = url
    },
    
    // 文件上传API调用
    async uploadSongFile(file) {
      try {
        return await fileUpload.uploadSong(file)
      } catch (error) {
        console.error('上传音乐文件失败:', error)
        throw error
      }
    },
    
    async uploadCoverFile(file) {
      try {
        return await fileUpload.uploadCover(file)
      } catch (error) {
        console.error('上传封面文件失败:', error)
        throw error
      }
    },
    
    closeCategoryModal() {
      this.showCategoryModal = false
      this.categoryForm = { name: '', description: '' }
    },
    
    async changePage(page) {
      if (page >= 0 && page < this.totalPages) {
        this.currentPage = page
        await this.loadMusic()
      }
    },
    
    searchMusic() {
      // 实现搜索功能
      console.log('搜索:', this.searchKeyword)
    },
    
    filterByCategory() {
      // 实现分类过滤功能
      console.log('过滤分类:', this.selectedCategory)
    },
    
    formatDuration(seconds) {
      // 处理各种输入情况
      if (seconds === null || seconds === undefined || seconds === 0) return '-'
      
      // 确保是数字类型
      const numSeconds = Number(seconds)
      if (isNaN(numSeconds) || numSeconds < 0) return '-'
      
      // 计算分钟和秒
      const minutes = Math.floor(numSeconds / 60)
      const remainingSeconds = Math.floor(numSeconds % 60)
      
      // 格式化输出
      if (minutes >= 60) {
        // 超过1小时的情况
        const hours = Math.floor(minutes / 60)
        const remainingMinutes = minutes % 60
        return `${hours}:${remainingMinutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`
      } else {
        // 普通情况：分:秒
        return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`
      }
    },
    
    formatDate(dateString) {
      if (!dateString) return '-'
      return new Date(dateString).toLocaleDateString('zh-CN')
    },
    
    formatNumber(num) {
      if (num >= 1000000) {
        return (num / 1000000).toFixed(1) + 'M'
      } else if (num >= 1000) {
        return (num / 1000).toFixed(1) + 'K'
      }
      return num?.toString() || '0'
    },
    

    
    updateSelectAll() {
      this.selectAll = this.selectedMusicIds.length === this.musicList.length && this.musicList.length > 0
    },
    
    toggleSelectAll() {
      if (this.selectAll) {
        this.selectedMusicIds = this.musicList.map(music => music.musicId)
      } else {
        this.selectedMusicIds = []
      }
    },
    
    async batchDeleteMusic() {
      if (this.selectedMusicIds.length === 0) {
        this.$root.showToast('请先选择要删除的音乐', 'warning')
        return
      }
      
      const count = this.selectedMusicIds.length
      if (!confirm(`确定要删除选中的 ${count} 首音乐吗？此操作不可撤销，相关文件也将被删除。`)) {
        return
      }
      
      this.batchDeleting = true
      try {
        // 逐个删除音乐（因为需要删除关联文件）
        let successCount = 0
        let failCount = 0
        
        for (const musicId of this.selectedMusicIds) {
          try {
            const response = await musicManagement.deleteMusic(musicId)
            if (response.success) {
              successCount++
            } else {
              failCount++
            }
          } catch (error) {
            console.error(`删除音乐 ${musicId} 失败:`, error)
            failCount++
          }
        }
        
        // 重新加载音乐列表
        await this.loadMusic()
        
        // 清空选择
        this.selectedMusicIds = []
        this.selectAll = false
        
        // 显示结果
        if (successCount > 0 && failCount === 0) {
          this.$root.showToast(`成功删除 ${successCount} 首音乐`, 'success')
        } else if (successCount > 0 && failCount > 0) {
          this.$root.showToast(`成功删除 ${successCount} 首，失败 ${failCount} 首`, 'warning')
        } else {
          this.$root.showToast('批量删除失败', 'error')
        }
      } catch (error) {
        console.error('批量删除失败:', error)
        this.$root.showToast('批量删除失败', 'error')
      } finally {
        this.batchDeleting = false
      }
    },
    
    // URL验证和测试相关方法
    validateMusicUrl() {
      const url = this.musicForm.musicUrl?.trim()
      if (!url) {
        this.urlValidation = { message: '', type: 'info' }
        return
      }
      
      try {
        new URL(url) // 验证URL格式
        
        // 检查是否为支持的音频格式
        if (this.isAudioUrl(url)) {
          this.urlValidation = {
            message: '✅ URL格式正确，建议点击测试按钮验证播放',
            type: 'success'
          }
        } else {
          this.urlValidation = {
            message: '⚠️ 可能不是音频文件URL，请确认链接正确',
            type: 'warning'
          }
        }
      } catch (error) {
        this.urlValidation = {
          message: '❌ URL格式不正确，请检查输入',
          type: 'error'
        }
      }
    },
    
    isAudioUrl(url) {
      // 检查是否为直接音频文件
      if (/\.(mp3|wav|ogg|flac|m4a|aac)$/i.test(url)) {
        return true
      }
      
      // 检查是否为支持的音乐平台
      const supportedDomains = [
        'music.163.com',
        'y.qq.com',
        'stream.qqmusic.qq.com',
        'kugou.com',
        'kuwo.cn',
        'soundcloud.com'
      ]
      
      return supportedDomains.some(domain => url.includes(domain))
    },
    
    async testMusicUrl() {
      const url = this.musicForm.musicUrl?.trim()
      if (!url) {
        this.$root.showToast('请先输入URL', 'warning')
        return
      }
      
      this.testingUrl = true
      try {
        await this.testAudioUrl(url)
      } finally {
        this.testingUrl = false
      }
    },
    
    async testAudioUrl(url) {
      try {
        console.log('🧪 测试音频URL:', url)
        
        // 创建音频元素进行测试
        const audio = new Audio()
        
        // 设置超时
        const timeout = new Promise((_, reject) =>
          setTimeout(() => reject(new Error('测试超时')), 10000)
        )
        
        // 等待音频加载
        const loadPromise = new Promise((resolve, reject) => {
          audio.addEventListener('canplay', () => {
            console.log('✅ 音频可以播放')
            resolve(true)
          }, { once: true })
          
          audio.addEventListener('error', (e) => {
            console.error('❌ 音频加载失败:', e)
            reject(new Error('音频加载失败'))
          }, { once: true })
          
          // 设置音频源
          if (this.isAudioUrl(url) && !url.includes('localhost')) {
            // 外部URL，使用代理
            const proxyUrl = `http://localhost:2025/api/audio/stream?url=${encodeURIComponent(url)}`
            audio.crossOrigin = 'use-credentials'
            audio.src = proxyUrl
          } else {
            // 直接URL或本地URL
            audio.crossOrigin = 'anonymous'
            audio.src = url
          }
        })
        
        await Promise.race([loadPromise, timeout])
        
        // 测试成功
        this.urlValidation = {
          message: '🎵 测试成功！音频可以正常播放',
          type: 'success'
        }
        this.$root.showToast('音频测试成功', 'success')
        
        // 设置预览
        this.previewAudioUrl = audio.src
        
      } catch (error) {
        console.error('音频测试失败:', error)
        this.urlValidation = {
          message: `❌ 测试失败: ${error.message}`,
          type: 'error'
        }
        this.$root.showToast(`音频测试失败: ${error.message}`, 'error')
      }
    },
    
    useTestUrl(testUrl) {
      this.musicForm.musicUrl = testUrl
      this.validateMusicUrl()
      this.$root.showToast('已使用测试URL', 'success')
    },
    
    clearPreview() {
      this.previewAudioUrl = ''
      this.urlValidation = { message: '', type: 'info' }
    },
    
    // 平台相关方法
    getCurrentPlatform() {
      return this.testAudioUrls.find(p => p.platform === this.selectedPlatform) || this.testAudioUrls[0]
    },
    
    generateUrlFromId() {
      if (!this.musicId.trim()) {
        this.musicForm.musicUrl = ''
        return
      }
      
      const platform = this.getCurrentPlatform()
      let generatedUrl = platform.urlTemplate
      
      // 替换模板中的占位符
      switch (platform.platform) {
        case 'netease':
          generatedUrl = generatedUrl.replace('{ID}', this.musicId.trim())
          break
        case 'qq':
          generatedUrl = generatedUrl.replace('{MID}', this.musicId.trim())
          break
        case 'kugou':
          generatedUrl = generatedUrl.replace('{HASH}', this.musicId.trim())
          break
        case 'custom':
          generatedUrl = this.musicId.trim() // 直接使用输入的URL
          break
      }
      
      this.musicForm.musicUrl = generatedUrl
      console.log('生成的URL:', generatedUrl)
    },
    
    async testGeneratedUrl() {
      if (!this.musicId.trim()) {
        const platform = this.getCurrentPlatform()
        const message = platform.platform === 'custom' ? '请先输入音频URL' : '请先输入音乐ID'
        this.$root.showToast(message, 'warning')
        return
      }
      
      this.generateUrlFromId()
      
      this.testingUrl = true
      try {
        await this.testAudioUrl(this.musicForm.musicUrl)
      } finally {
        this.testingUrl = false
      }
    },
    
    // 自动检测音乐平台
    detectMusicPlatform(musicUrl) {
      if (!musicUrl) {
        this.selectedPlatform = 'netease'
        this.musicId = ''
        return
      }
      
      // 检测网易云音乐
      if (musicUrl.includes('music.163.com')) {
        this.selectedPlatform = 'netease'
        const match = musicUrl.match(/id[=\/](\d+)/)
        this.musicId = match ? match[1] : ''
      }
      // 检测QQ音乐
      else if (musicUrl.includes('qqmusic.qq.com') || musicUrl.includes('stream.qqmusic.qq.com')) {
        this.selectedPlatform = 'qq'
        const match = musicUrl.match(/([A-Za-z0-9]{14,})\.m4a/)
        this.musicId = match ? match[1] : ''
      }
      // 检测酷狗音乐
      else if (musicUrl.includes('kugou.com')) {
        this.selectedPlatform = 'kugou'
        const match = musicUrl.match(/([A-F0-9]{20,})\.mp3/)
        this.musicId = match ? match[1] : ''
      }
      // 其他自定义URL
      else {
        this.selectedPlatform = 'custom'
        this.musicId = musicUrl
      }
      
             console.log('检测到音乐平台:', this.selectedPlatform, '音乐ID:', this.musicId)
     },
     
     // 封面URL相关方法
     updateCoverPreview() {
       // 清除之前的状态
       this.coverUrlStatus = null
       
       // 如果URL为空，也清除预览
       if (!this.musicForm.coverUrl) {
         this.musicForm.coverPreview = null
       }
     },
     
     testCoverUrl() {
       if (!this.musicForm.coverUrl) {
         this.$root.showToast('请先输入封面图片URL', 'warning')
         return
       }
       
       this.coverUrlStatus = { type: 'info', message: '正在测试图片...' }
       
       // 创建新图片元素测试
       const img = new Image()
       img.onload = () => {
         this.coverUrlStatus = { type: 'success', message: '图片可正常访问' }
         this.musicForm.coverPreview = this.musicForm.coverUrl
       }
       img.onerror = () => {
         this.coverUrlStatus = { type: 'error', message: '图片无法访问或URL无效' }
         this.musicForm.coverPreview = null
       }
       img.src = this.musicForm.coverUrl
     },
     
     onCoverLoad() {
       if (!this.coverUrlStatus || this.coverUrlStatus.type !== 'error') {
         this.coverUrlStatus = { type: 'success', message: '图片加载成功' }
         this.musicForm.coverPreview = this.musicForm.coverUrl
       }
     },
     
     onCoverError() {
       this.coverUrlStatus = { type: 'error', message: '图片加载失败' }
       this.musicForm.coverPreview = null
     }
  },
  
  watch: {
    // 监听时长字段的变化，判断是否为手动输入
    'musicForm.duration'(newValue, oldValue) {
      // 如果时长发生变化，判断是否为手动输入
      // 排除初始化和重置的情况
      if (newValue !== oldValue && oldValue !== undefined) {
        // 如果不是从音频文件自动获取的，则标记为手动设置
        if (!this.isFromAudioFile) {
          this.manualDuration = true
          console.log('检测到手动设置时长:', newValue)
        }
      }
    }
  }
}
</script>

<style scoped>
/* 音乐管理页面样式 */
.music-management {
  padding: 32px;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 32px;
}

.header-left h1 {
  font-size: 32px;
  font-weight: 700;
  margin: 0 0 8px 0;
  color: white;
}

.page-subtitle {
  color: #b3b3b3;
  margin: 0;
}

.primary-btn {
  background: #1db954;
  color: white;
  border: none;
  padding: 12px 24px;
  border-radius: 8px;
  font-weight: 600;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
  transition: all 0.3s ease;
}

.primary-btn:hover {
  background: #1ed760;
  transform: translateY(-1px);
}

/* 搜索和过滤 */
.filters {
  display: flex;
  gap: 16px;
  margin-bottom: 24px;
}

.search-box {
  position: relative;
  flex: 1;
  max-width: 400px;
}

.search-box svg {
  position: absolute;
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
  color: #b3b3b3;
}

.search-box input {
  width: 100%;
  background: #1a1a1a;
  border: 1px solid #282828;
  border-radius: 8px;
  padding: 12px 12px 12px 40px;
  color: white;
  font-size: 14px;
}

.search-box input:focus {
  outline: none;
  border-color: #1db954;
}

.category-filter {
  background: #1a1a1a;
  border: 1px solid #282828;
  border-radius: 8px;
  padding: 12px 16px;
  color: white;
  min-width: 150px;
}

/* 音乐表格 */
.music-table-container {
  background: #1a1a1a;
  border-radius: 12px;
  overflow: hidden;
  margin-bottom: 24px;
}

.music-table {
  width: 100%;
  border-collapse: collapse;
}

.music-table th {
  background: #282828;
  color: #b3b3b3;
  padding: 16px;
  text-align: left;
  font-weight: 600;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.music-table td {
  padding: 16px;
  border-bottom: 1px solid #282828;
  vertical-align: middle;
}

.music-row:hover {
  background: #282828;
}

.music-cover {
  width: 50px;
  height: 50px;
  border-radius: 6px;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #282828;
}

.music-cover img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.default-cover {
  color: #b3b3b3;
}

.music-title {
  color: white;
  font-weight: 600;
}

.category-tag {
  background: #1db954;
  color: black;
  padding: 4px 8px;
  border-radius: 12px;
  font-size: 12px;
  font-weight: 600;
  margin-right: 4px;
}

.action-buttons {
  display: flex;
  gap: 8px;
}

.edit-btn,
.delete-btn {
  background: transparent;
  border: none;
  color: #b3b3b3;
  cursor: pointer;
  padding: 8px;
  border-radius: 6px;
  transition: all 0.3s ease;
}

.edit-btn:hover {
  background: rgba(29, 185, 84, 0.1);
  color: #1db954;
}

.delete-btn:hover {
  background: rgba(255, 107, 107, 0.1);
  color: #ff6b6b;
}

/* 分页 */
.pagination {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 24px;
}

.page-btn {
  background: #1a1a1a;
  color: white;
  border: 1px solid #282828;
  padding: 8px 16px;
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.3s ease;
}

.page-btn:hover:not(:disabled) {
  background: #282828;
}

.page-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.page-info {
  color: #b3b3b3;
  font-size: 14px;
}

/* 模态框样式 */
.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.8);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  padding: 20px;
}

.modal-content {
  background: #1a1a1a;
  border-radius: 12px;
  max-width: 1000px;
  width: 100%;
  max-height: 95vh;
  display: flex;
  flex-direction: column;
}

.category-modal {
  max-width: 1000px;
  max-height: 80vh;
}

.modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 24px;
  border-bottom: 1px solid #282828;
}

.modal-header h3 {
  margin: 0;
  color: white;
  font-size: 20px;
}

.close-btn {
  background: transparent;
  border: none;
  color: #b3b3b3;
  cursor: pointer;
  padding: 4px;
  border-radius: 4px;
  transition: all 0.3s ease;
}

.close-btn:hover {
  color: white;
  background: #282828;
}

.modal-body {
  padding: 24px;
  overflow-y: auto;
  flex: 1;
}

.form-group {
  margin-bottom: 20px;
}

.form-group label {
  display: block;
  margin-bottom: 8px;
  color: white;
  font-weight: 600;
}

.form-group input,
.form-group select,
.form-group textarea {
  width: 100%;
  background: #282828;
  border: 1px solid #404040;
  border-radius: 8px;
  padding: 12px;
  color: white;
  font-size: 14px;
}

.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
  outline: none;
  border-color: #1db954;
}

.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 16px;
}

.form-row.two-col {
  grid-template-columns: 1fr 1fr;
}

/* 时长输入样式 */
.duration-input {
  position: relative;
}

.duration-input input {
  width: 100%;
  background: #282828;
  border: 1px solid #404040;
  border-radius: 8px;
  padding: 12px 16px;
  color: white;
  font-size: 14px;
}

/* 隐藏number输入框的上下箭头 */
.duration-input input[type="number"]::-webkit-outer-spin-button,
.duration-input input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.duration-input input[type="number"] {
  -moz-appearance: textfield;
}

.duration-input input.auto-detected {
  border-color: #22c55e;
  background: rgba(34, 197, 94, 0.05);
}

.duration-input .duration-display {
  position: absolute;
  top: 50%;
  right: 80px;
  transform: translateY(-50%);
  background: rgba(34, 197, 94, 0.1);
  border: 1px solid #22c55e;
  color: #22c55e;
  font-size: 12px;
  padding: 4px 8px;
  border-radius: 4px;
  font-weight: 500;
  pointer-events: none;
}

.duration-input .auto-label {
  position: absolute;
  top: 50%;
  right: 16px;
  transform: translateY(-50%);
  background: #22c55e;
  color: white;
  font-size: 11px;
  padding: 4px 8px;
  border-radius: 4px;
  font-weight: 600;
  pointer-events: none;
  letter-spacing: 0.5px;
}

.duration-input .manual-label {
  position: absolute;
  top: 50%;
  right: 16px;
  transform: translateY(-50%);
  background: #1db954;
  color: white;
  font-size: 11px;
  padding: 4px 8px;
  border-radius: 4px;
  font-weight: 600;
  pointer-events: none;
  letter-spacing: 0.5px;
}

/* 播放次数输入样式 */
.play-count-input {
  position: relative;
}

.play-count-input input {
  width: 100%;
  background: #282828;
  border: 1px solid #404040;
  border-radius: 8px;
  padding: 12px 16px;
  color: white;
  font-size: 14px;
}

/* 隐藏播放次数输入框的上下箭头 */
.play-count-input input[type="number"]::-webkit-outer-spin-button,
.play-count-input input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.play-count-input input[type="number"] {
  -moz-appearance: textfield;
}

.play-count-input .count-display {
  position: absolute;
  top: 50%;
  right: 16px;
  transform: translateY(-50%);
  background: rgba(29, 185, 84, 0.1);
  border: 1px solid #1db954;
  color: #1db954;
  font-size: 12px;
  padding: 4px 8px;
  border-radius: 4px;
  font-weight: 500;
  pointer-events: none;
}

/* 表单区域样式 */
.form-section {
  margin-bottom: 32px;
  padding-bottom: 24px;
  border-bottom: 1px solid #333;
}

.form-section:last-child {
  border-bottom: none;
  margin-bottom: 0;
  padding-bottom: 0;
}

.section-title {
  color: #1db954;
  font-size: 18px;
  font-weight: 600;
  margin: 0 0 20px 0;
  display: flex;
  align-items: center;
  gap: 8px;
}

.section-title::before {
  content: '';
  display: block;
  width: 4px;
  height: 20px;
  background: #1db954;
  border-radius: 2px;
}

/* 上传容器布局 */
.upload-container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
}

.upload-column {
  display: flex;
  flex-direction: column;
}

.upload-label {
  color: white;
  font-weight: 600;
  margin-bottom: 12px;
  font-size: 16px;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .form-row {
    grid-template-columns: 1fr 1fr;
  }
  
  .upload-container {
    grid-template-columns: 1fr;
    gap: 20px;
  }
  
  .duration-input .duration-display {
    right: 70px;
  }
  
  .duration-input .auto-label,
  .duration-input .manual-label {
    right: 12px;
    font-size: 10px;
    padding: 3px 6px;
  }
}

@media (max-width: 480px) {
  .form-row {
    grid-template-columns: 1fr;
  }
  
  .upload-container {
    grid-template-columns: 1fr;
    gap: 16px;
  }
  
  .modal-content {
    max-width: 95vw;
    margin: 10px;
  }
  
  .duration-input .duration-display {
    right: 65px;
    font-size: 11px;
    padding: 3px 6px;
  }
  
  .duration-input .auto-label,
  .duration-input .manual-label {
    right: 10px;
    font-size: 9px;
    padding: 2px 5px;
  }
}

.modal-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  padding: 20px 24px;
  border-top: 1px solid #282828;
  background: #1a1a1a;
  border-radius: 0 0 12px 12px;
  flex-shrink: 0;
}

.cancel-btn,
.submit-btn {
  padding: 12px 24px;
  border-radius: 8px;
  font-weight: 600;
  cursor: pointer;
  border: none;
  transition: all 0.3s ease;
}

.cancel-btn {
  background: #282828;
  color: white;
}

.cancel-btn:hover {
  background: #404040;
}

.submit-btn {
  background: #1db954;
  color: white;
}

.submit-btn:hover {
  background: #1ed760;
}

.submit-btn:disabled {
  background: #404040;
  cursor: not-allowed;
}

/* 分类管理样式 */
.category-management-layout {
  display: grid;
  grid-template-columns: 400px 1fr;
  gap: 32px;
  height: 100%;
}

.category-form-section,
.category-list-section {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.section-header {
  margin-bottom: 20px;
  padding-bottom: 16px;
  border-bottom: 2px solid #1db954;
}

.section-header h4 {
  margin: 0 0 8px 0;
  color: #1db954;
  font-size: 18px;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 8px;
}

.section-header h4::before {
  content: '';
  display: block;
  width: 4px;
  height: 20px;
  background: #1db954;
  border-radius: 2px;
}

.section-description {
  color: #b3b3b3;
  font-size: 14px;
  margin: 0;
}

.category-form {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.category-form .form-group {
  margin-bottom: 0;
}

.add-btn {
  background: linear-gradient(135deg, #1db954, #1ed760);
  color: white;
  border: none;
  padding: 14px 24px;
  border-radius: 8px;
  font-weight: 600;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
  transition: all 0.3s ease;
  box-shadow: 0 2px 8px rgba(29, 185, 84, 0.3);
  align-self: flex-start;
}

.add-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 16px rgba(29, 185, 84, 0.4);
}

.add-btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  transform: none;
}

.category-list-section {
  min-height: 0;
}

.category-list {
  flex: 1;
  overflow-y: auto;
  min-height: 0;
}

.empty-state {
  text-align: center;
  padding: 40px 20px;
  color: #666;
}

.empty-state svg {
  margin-bottom: 16px;
  opacity: 0.5;
}

.empty-state p {
  margin: 0 0 8px 0;
  color: #888;
  font-size: 16px;
  font-weight: 500;
}

.empty-state span {
  color: #666;
  font-size: 14px;
}

.category-items {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding-right: 8px;
}

.category-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px;
  background: #282828;
  border-radius: 12px;
  border: 1px solid #404040;
  transition: all 0.3s ease;
}

.category-item:hover {
  background: #333;
  border-color: #1db954;
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}

.category-main {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.category-info strong {
  color: white;
  font-size: 16px;
  font-weight: 600;
}

.category-desc {
  color: #b3b3b3;
  font-size: 14px;
  margin: 0;
}

.category-actions {
  display: flex;
  gap: 12px;
  flex-shrink: 0;
}

.category-actions .edit-btn,
.category-actions .delete-btn {
  padding: 8px 16px;
  font-size: 14px;
  border-radius: 6px;
  border: none;
  cursor: pointer;
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 6px;
  transition: all 0.3s ease;
}

.category-actions .edit-btn {
  background: linear-gradient(135deg, #007bff, #0056b3);
  color: white;
}

.category-actions .edit-btn:hover {
  background: linear-gradient(135deg, #0056b3, #004085);
  transform: translateY(-1px);
  box-shadow: 0 2px 8px rgba(0, 123, 255, 0.3);
}

.category-actions .delete-btn {
  background: linear-gradient(135deg, #dc3545, #c82333);
  color: white;
}

.category-actions .delete-btn:hover {
  background: linear-gradient(135deg, #c82333, #a71e2a);
  transform: translateY(-1px);
  box-shadow: 0 2px 8px rgba(220, 53, 69, 0.3);
}

/* 响应式设计 */
@media (max-width: 768px) {
  .category-management-layout {
    grid-template-columns: 1fr;
    gap: 24px;
  }
  
  .category-form-section {
    order: 1;
  }
  
  .category-list-section {
    order: 2;
  }
}

/* 文件上传样式 */
.upload-section {
  border: 1px solid #404040;
  border-radius: 8px;
  overflow: hidden;
  height: fit-content;
}

.upload-tabs {
  display: flex;
  background: #282828;
}

.upload-tab {
  flex: 1;
  padding: 12px 16px;
  border: none;
  background: transparent;
  color: #b3b3b3;
  cursor: pointer;
  transition: all 0.3s ease;
  border-bottom: 2px solid transparent;
}

.upload-tab.active {
  color: #1db954;
  border-bottom-color: #1db954;
}

.upload-tab:hover {
  color: white;
}

.upload-area {
  padding: 20px;
}

.file-input {
  display: none;
}

.file-label {
  display: block;
  cursor: pointer;
  transition: all 0.3s ease;
}

.upload-placeholder {
  text-align: center;
  padding: 40px 20px;
  border: 2px dashed #404040;
  border-radius: 8px;
  transition: all 0.3s ease;
}

.upload-placeholder:hover {
  border-color: #1db954;
  background: rgba(29, 185, 84, 0.05);
}

.upload-placeholder svg {
  color: #b3b3b3;
  margin-bottom: 16px;
}

.upload-placeholder p {
  margin: 0;
  color: white;
  font-weight: 600;
}

.upload-hint {
  margin-top: 8px !important;
  color: #b3b3b3 !important;
  font-size: 14px !important;
  font-weight: normal !important;
}

.upload-success {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px;
  background: rgba(29, 185, 84, 0.1);
  border: 1px solid #1db954;
  border-radius: 8px;
  color: #1db954;
}

.upload-success svg {
  flex-shrink: 0;
}

.upload-success span {
  flex: 1;
  color: white;
}

.clear-btn {
  background: linear-gradient(135deg, #FF9800, #F57C00);
  color: white;
  border: none;
  padding: 12px 24px;
  border-radius: 8px;
  cursor: pointer;
  font-size: 14px;
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 8px;
  transition: all 0.3s ease;
  box-shadow: 0 2px 8px rgba(255, 152, 0, 0.3);
}

.clean-btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  transform: none;
  box-shadow: 0 2px 8px rgba(255, 152, 0, 0.3);
}

/* URL示例和提示区域优化 */
.url-examples {
  max-height: 400px;
  overflow-y: auto;
}

.platform-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
  margin-bottom: 20px;
}

.platform-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px;
  background: #2a2a2a;
  border-radius: 6px;
  border: 1px solid #404040;
}

.platform-info {
  flex: 1;
  margin-right: 12px;
}

.platform-info strong {
  color: white;
  display: block;
  margin-bottom: 4px;
}

.platform-info p {
  color: #b3b3b3;
  font-size: 13px;
  margin: 0;
}

.platform-actions {
  display: flex;
  gap: 8px;
}

.url-hint {
  background: #2a2a2a;
  padding: 16px;
  border-radius: 8px;
  border: 1px solid #404040;
}

.hint-title {
  color: #1db954;
  font-weight: 600;
  margin: 0 0 12px 0;
}

.hint-list {
  margin: 0 0 12px 0;
  padding-left: 20px;
}

.hint-list li {
  color: #b3b3b3;
  font-size: 13px;
  margin-bottom: 6px;
}

.hint-note {
  color: #ff9800;
  font-size: 13px;
  margin: 0;
  font-style: italic;
}

/* 平台选择器样式 */
.platform-selector {
  margin-bottom: 20px;
}

.platform-select-label {
  color: white;
  font-weight: 600;
  display: block;
  margin-bottom: 12px;
}

.platform-buttons {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.platform-btn {
  background: #282828;
  color: #b3b3b3;
  border: 1px solid #404040;
  padding: 8px 16px;
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.3s ease;
  font-size: 14px;
}

.platform-btn:hover {
  color: white;
  border-color: #1db954;
}

.platform-btn.active {
  background: #1db954;
  color: white;
  border-color: #1db954;
}

/* ID输入样式 */
.id-input-section {
  margin-bottom: 16px;
}

.id-input-group {
  display: flex;
  gap: 8px;
  margin-bottom: 12px;
}

.id-input-group input {
  flex: 1;
  background: #282828;
  border: 1px solid #404040;
  border-radius: 8px;
  padding: 12px;
  color: white;
  font-size: 14px;
}

.id-input-group input:focus {
  outline: none;
  border-color: #1db954;
}

.platform-example {
  margin-bottom: 12px;
}

.example-text {
  color: #b3b3b3;
  font-size: 13px;
}

.generated-url {
  margin-bottom: 12px;
}

.generated-url label {
  color: white;
  font-weight: 600;
  display: block;
  margin-bottom: 8px;
}

.url-display {
  background: #2a2a2a;
  border: 1px solid #404040;
  border-radius: 6px;
  padding: 8px 12px;
  color: #1db954;
  font-family: monospace;
  font-size: 13px;
  word-break: break-all;
}

/* 批量操作样式 */
.batch-toolbar {
  background: linear-gradient(135deg, #f8f9fa, #e9ecef);
  border: 1px solid #dee2e6;
  border-radius: 8px;
  padding: 12px 16px;
  margin-bottom: 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.selected-count {
  color: #495057;
  font-weight: 500;
  font-size: 14px;
}

.batch-delete-btn {
  background: linear-gradient(135deg, #dc3545, #c82333);
  color: white;
  border: none;
  padding: 8px 16px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 14px;
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 8px;
  transition: all 0.3s ease;
  box-shadow: 0 2px 8px rgba(220, 53, 69, 0.3);
}

.batch-delete-btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(220, 53, 69, 0.4);
}

.batch-delete-btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  transform: none;
  box-shadow: 0 2px 8px rgba(220, 53, 69, 0.3);
}

.batch-delete-btn-filter {
  background: linear-gradient(135deg, #dc3545, #c82333);
  color: white;
  border: none;
  padding: 10px 16px;
  border-radius: 8px;
  cursor: pointer;
  font-size: 14px;
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 8px;
  transition: all 0.3s ease;
  box-shadow: 0 2px 8px rgba(220, 53, 69, 0.3);
  margin-left: 12px;
  height: 42px;
}

.batch-delete-btn-filter:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(220, 53, 69, 0.4);
}

.batch-delete-btn-filter:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  transform: none;
  box-shadow: 0 2px 8px rgba(220, 53, 69, 0.3);
}

.checkbox-col {
  width: 50px;
  text-align: center;
}

.checkbox {
  width: 18px;
  height: 18px;
  cursor: pointer;
  accent-color: #4CAF50;
}

.music-table th.checkbox-col,
.music-table td.checkbox-col {
  padding: 8px;
  text-align: center;
  vertical-align: middle;
}

.upload-btn {
  background: linear-gradient(135deg, #4CAF50, #45a049);
  color: white;
  border: none;
  padding: 12px 24px;
  border-radius: 8px;
  cursor: pointer;
  font-size: 14px;
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 8px;
  transition: all 0.3s ease;
  box-shadow: 0 2px 8px rgba(76, 175, 80, 0.3);
}

.upload-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 16px rgba(76, 175, 80, 0.4);
}

/* URL输入相关样式 */
.upload-tab.priority {
  background: linear-gradient(135deg, #1db954, #1ed760);
  color: white;
  font-weight: 600;
  position: relative;
}

.upload-tab.priority::after {
  content: '推荐';
  position: absolute;
  top: 13px;
  right: 32px;
  background: #ff4757;
  color: white;
  font-size: 10px;
  padding: 2px 6px;
  border-radius: 10px;
  font-weight: 500;
}

.upload-tab.not-recommended {
  background: linear-gradient(135deg, #6c757d, #5a6268);
  color: white;
  font-weight: 600;
  position: relative;
}

.upload-tab.not-recommended::after {
  content: '测试';
  position: absolute;
  top: 13px;
  right: 22px;
  background: #dc3545;
  color: white;
  font-size: 10px;
  padding: 2px 6px;
  border-radius: 10px;
  font-weight: 500;
}

.upload-tab.not-recommended.active {
  background: linear-gradient(135deg, #495057, #343a40);
  border-color: #dc3545;
}

.url-input {
  margin-top: 16px;
}

.url-input input[type="url"] {
  width: 100%;
  padding: 12px 16px;
  border: 2px solid #404040;
  border-radius: 8px;
  background: #1a1a1a;
  color: white;
  font-size: 14px;
  transition: all 0.3s ease;
}

.url-input input[type="url"]:focus {
  border-color: #1db954;
  box-shadow: 0 0 0 3px rgba(29, 185, 84, 0.1);
  outline: none;
}

.url-hints {
  margin-top: 12px;
  padding: 16px;
  background: rgba(29, 185, 84, 0.05);
  border: 1px solid rgba(29, 185, 84, 0.2);
  border-radius: 8px;
}

.hint-title {
  margin: 0 0 8px 0;
  color: #1db954;
  font-weight: 600;
  font-size: 14px;
}

.hint-list {
  margin: 8px 0;
  padding-left: 0;
  list-style: none;
}

.hint-list li {
  margin: 4px 0;
  color: #b3b3b3;
  font-size: 13px;
}

.hint-example {
  margin: 8px 0 0 0;
  color: #1db954;
}

/* URL输入组件样式 */
.url-input-section {
  margin-bottom: 16px;
}

.url-input-group {
  display: flex;
  gap: 8px;
  align-items: center;
}

.url-input-group input {
  flex: 1;
}

.btn {
  padding: 8px 16px;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  font-size: 14px;
  font-weight: 500;
  transition: all 0.3s ease;
  display: flex;
  align-items: center;
  gap: 4px;
}

.btn-test {
  background: linear-gradient(135deg, #ff9800, #f57c00);
  color: white;
  min-width: 80px;
  justify-content: center;
}

.btn-test:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(255, 152, 0, 0.3);
}

.btn-test:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  transform: none;
}

.btn-sm {
  padding: 6px 12px;
  font-size: 12px;
}

.btn-outline {
  background: transparent;
  border: 1px solid #404040;
  color: #b3b3b3;
}

.btn-outline:hover {
  background: #404040;
  color: white;
}

/* URL验证状态样式 */
.url-validation {
  margin-top: 8px;
  padding: 8px 12px;
  border-radius: 6px;
  font-size: 13px;
  font-weight: 500;
}

.url-validation.success {
  background: rgba(76, 175, 80, 0.1);
  color: #4caf50;
  border: 1px solid rgba(76, 175, 80, 0.3);
}

.url-validation.error {
  background: rgba(244, 67, 54, 0.1);
  color: #f44336;
  border: 1px solid rgba(244, 67, 54, 0.3);
}

.url-validation.warning {
  background: rgba(255, 152, 0, 0.1);
  color: #ff9800;
  border: 1px solid rgba(255, 152, 0, 0.3);
}

.url-validation.info {
  background: rgba(33, 150, 243, 0.1);
  color: #2196f3;
  border: 1px solid rgba(33, 150, 243, 0.3);
}

/* URL示例样式 */
.url-examples {
  margin-top: 16px;
  padding: 16px;
  background: rgba(255, 255, 255, 0.02);
  border: 1px solid #404040;
  border-radius: 8px;
}

.url-examples h5 {
  margin: 0 0 12px 0;
  color: #1db954;
  font-size: 14px;
  font-weight: 600;
}

.platform-grid {
  display: grid;
  gap: 12px;
  margin-bottom: 16px;
}

.platform-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px;
  background: #1a1a1a;
  border: 1px solid #404040;
  border-radius: 6px;
  transition: all 0.3s ease;
}

.platform-item:hover {
  border-color: #1db954;
  background: rgba(29, 185, 84, 0.05);
}

.platform-info strong {
  color: white;
  font-size: 14px;
  margin-bottom: 4px;
  display: block;
}

.platform-info p {
  color: #b3b3b3;
  font-size: 12px;
  margin: 0;
}

.platform-actions {
  display: flex;
  gap: 8px;
}

.url-hint {
  margin-top: 16px;
  padding: 12px;
  background: rgba(29, 185, 84, 0.05);
  border: 1px solid rgba(29, 185, 84, 0.2);
  border-radius: 6px;
}

.hint-title {
  margin: 0 0 8px 0;
  color: #1db954;
  font-weight: 600;
  font-size: 13px;
}

.hint-list {
  margin: 8px 0;
  padding-left: 16px;
  list-style: none;
}

.hint-list li {
  margin: 4px 0;
  color: #b3b3b3;
  font-size: 12px;
  position: relative;
}

.hint-note {
  margin: 8px 0 0 0;
  color: #ff9800;
  font-size: 12px;
  font-style: italic;
}

/* 音频预览样式 */
.audio-preview {
  margin-top: 16px;
  padding: 16px;
  background: rgba(29, 185, 84, 0.1);
  border: 1px solid rgba(29, 185, 84, 0.3);
  border-radius: 8px;
}

.audio-preview h5 {
  margin: 0 0 12px 0;
  color: #1db954;
  font-size: 14px;
  font-weight: 600;
}

.audio-preview audio {
  width: 100%;
  margin-bottom: 12px;
  background: #1a1a1a;
  border-radius: 6px;
}

/* 封面预览样式 */
.cover-url-preview {
  margin-top: 16px;
  padding: 16px;
  background: rgba(29, 185, 84, 0.1);
  border: 1px solid rgba(29, 185, 84, 0.3);
  border-radius: 8px;
}

.cover-url-preview h5 {
  margin: 0 0 12px 0;
  color: #1db954;
  font-size: 14px;
  font-weight: 600;
}

.preview-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}

.preview-image {
  max-width: 200px;
  max-height: 200px;
  width: auto;
  height: auto;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
  transition: transform 0.3s ease;
}

.preview-image:hover {
  transform: scale(1.05);
}

.preview-status {
  padding: 8px 12px;
  border-radius: 6px;
  font-size: 13px;
  font-weight: 500;
  text-align: center;
  min-width: 150px;
}

.preview-status.success {
  background: rgba(76, 175, 80, 0.1);
  color: #4caf50;
  border: 1px solid rgba(76, 175, 80, 0.3);
}

.preview-status.error {
  background: rgba(244, 67, 54, 0.1);
  color: #f44336;
  border: 1px solid rgba(244, 67, 54, 0.3);
}

.preview-status.info {
  background: rgba(33, 150, 243, 0.1);
  color: #2196f3;
  border: 1px solid rgba(33, 150, 243, 0.3);
}

.url-input-group {
  display: flex;
  gap: 8px;
  align-items: center;
}

.url-input-group input {
  flex: 1;
}

/* 教程链接样式 */
.tutorial-link {
  color: #1db954;
  text-decoration: none;
  font-weight: 500;
  font-size: 14px;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 8px;
  border-radius: 4px;
  transition: all 0.3s ease;
}

.tutorial-link:hover {
  background: rgba(29, 185, 84, 0.1);
  color: #1ed760;
  text-decoration: none;
  transform: translateY(-1px);
}

.tutorial-link:focus {
  outline: 2px solid rgba(29, 185, 84, 0.3);
  outline-offset: 2px;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .platform-item {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }
  
  .platform-actions {
    width: 100%;
    justify-content: flex-end;
  }
  
  .url-input-group {
    flex-direction: column;
  }
  
  .url-input-group input {
    width: 100%;
  }
  
  .tutorial-link {
    font-size: 13px;
    padding: 3px 6px;
  }
}
</style> 